package com.gun3y.ts.helper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.gun3y.common.Pair;
import com.gun3y.entity.media.Data;
import com.gun3y.entity.media.Movie;
import com.gun3y.entity.media.PropertyType;
import com.gun3y.entity.media.WrapperDataProps;
import com.gun3y.entity.media.WrapperObjectProps;
import com.gun3y.utils.Commons;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.NodeFactory;
import com.hp.hpl.jena.graph.Triple;

public class TripleHelper {

    public static Node createTypePredicate() {
	return NodeFactory.createURI(Commons.RDF + "type");
    }

    public static Node createMovie() {
	return NodeFactory.createURI(Commons.MOVIE + "Movie");
    }

    public static Node createPredicate(PropertyType propertyType) {
	return NodeFactory.createURI(Commons.MOVIE + propertyType);
    }

    public static Node createNamePredicate() {
	return NodeFactory.createURI(Commons.MOVIE + "name");
    }

    public static Node createTextPredicate() {
	return NodeFactory.createURI(Commons.MOVIE + "text");
    }

    public static Node createFromPredicate() {
	return NodeFactory.createURI(Commons.MOVIE + "from");
    }

    public static Node createWrapper() {
	return NodeFactory.createURI(Commons.WRAPPER + "Wrapper");
    }

    public static Node createWrapperNamePredicate() {
	return NodeFactory.createURI(Commons.WRAPPER + "name");
    }

    public static Node createWrapperPredicate(WrapperDataProps dataProps) {
	return NodeFactory.createURI(Commons.WRAPPER + dataProps);
    }

    public static Node createWrapperPredicate(WrapperObjectProps objectProps) {
	return NodeFactory.createURI(Commons.WRAPPER + objectProps);
    }

    public static List<Triple> createTriples(Movie movie) {
	if (movie == null || StringUtils.isBlank(movie.getName())) {
	    return Collections.emptyList();
	}

	List<Triple> triples = new ArrayList<Triple>();

	Node movieNode = NodeFactory.createAnon();
	triples.add(new Triple(movieNode, createTypePredicate(), createMovie()));
	triples.add(new Triple(movieNode, createNamePredicate(), NodeFactory.createLiteral(movie.getName())));
	triples.addAll(createTriples(movieNode, PropertyType.actor, movie.getActors()));
	triples.addAll(createTriples(movieNode, PropertyType.contentRating, movie.getContentRating()));
	triples.addAll(createTriples(movieNode, PropertyType.creator, movie.getCreators()));
	triples.addAll(createTriples(movieNode, PropertyType.datePublished, movie.getDatePublished()));
	triples.addAll(createTriples(movieNode, PropertyType.description, movie.getDescription()));
	triples.addAll(createTriples(movieNode, PropertyType.director, movie.getDirectors()));
	triples.addAll(createTriples(movieNode, PropertyType.duration, movie.getDuration()));
	triples.addAll(createTriples(movieNode, PropertyType.genre, movie.getGenre()));
	triples.addAll(createTriples(movieNode, PropertyType.image, movie.getImage()));
	triples.addAll(createTriples(movieNode, PropertyType.keywords, movie.getKeyword()));

	triples.addAll(createTriples(movieNode, PropertyType.productionCompany, movie.getProductionCompany()));
	triples.addAll(createTriples(movieNode, PropertyType.provider, movie.getProvider()));
	triples.addAll(createTriples(movieNode, PropertyType.rating, movie.getRating()));
	triples.addAll(createTriples(movieNode, PropertyType.url, movie.getUrl()));
	return triples;
    }

    private static List<Triple> createTriples(Node movieNode, PropertyType propertyType, List<Data> dataList) {
	if (dataList == null || dataList.isEmpty() || movieNode == null) {
	    return Collections.emptyList();
	}
	List<Triple> triples = new ArrayList<Triple>();

	for (Data data : dataList) {
	    triples.addAll(createTriples(movieNode, propertyType, data));
	}

	return triples;
    }

    private static List<Triple> createTriples(Node movieNode, PropertyType propertyType, Data data) {
	if (data == null || !data.validate()) {
	    return Collections.emptyList();
	}

	List<Triple> triples = new ArrayList<Triple>();

	Pair<Node, List<Triple>> dataTriple = createDataTriples(data);
	Triple triple = new Triple(movieNode, NodeFactory.createURI(Commons.MOVIE + propertyType), dataTriple.getKey());
	triples.add(triple);
	triples.addAll(dataTriple.getValue());

	return triples;
    }

    private static Pair<Node, List<Triple>> createDataTriples(Data data) {
	String nodeName = data.getText() + "_" + data.getFrom();
	nodeName = nodeName.replaceAll("\\s+", "");

	Node d11 = NodeFactory.createAnon();
	Node d12 = NodeFactory.createURI(Commons.RDF + "type");
	Node d13 = NodeFactory.createURI(Commons.MOVIE + "Data");

	Node d22 = NodeFactory.createURI(Commons.MOVIE + "text");
	Node d23 = NodeFactory.createLiteral(data.getText());

	Node d32 = NodeFactory.createURI(Commons.MOVIE + "from");
	Node d33 = NodeFactory.createLiteral(data.getFrom());

	List<Triple> triples = Arrays.asList(new Triple(d11, d12, d13), new Triple(d11, d22, d23), new Triple(d11, d32, d33));

	return new Pair<Node, List<Triple>>(d11, triples);
    }

}
